/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   KKSManger.h
 * Author: ever
 *
 * Created on 2018年5月12日, 下午11:05
 */

#ifndef KKSMANGER_H
#define KKSMANGER_H


#include "TL_Singleton.h"
#include "TL_Datetime.h"
#include "TL_ThreadLock.h"
#include "KKSIndex.h"
#include "KKSFile.h"
#include <mutex>
#include <memory>
#include <map>
#include <vector>
#include <deque>
#include <sstream>

using namespace std;
#define ONE_DAY_SECONDS (24 * 60 * 60)
#define BEIJING_TIME (8 * 60 * 60)

class KKSManger : public tidp::TL_Singleton<KKSManger> {
public:
    KKSManger();

    KKSManger(const KKSManger &orig);

    virtual ~KKSManger();

    struct KKS_Value {
        u32_t kid;
        u32_t value;
        time_t tm = 0;
        char quality;
    };

    void setKKSFilePath(const string &kks_file_path, bool isIndex = false);

    KKSIndex &getKKSIndex();

    string getKKSPath(time_t t);

    u32_t addKKS(const string &kks);

    u32_t getKKSId(const string &kks);

    void saveIndex();

    void addKKSValue(u32_t id, u32_t tm, u32_t vl, u8_t quality);

    std::shared_ptr<KKSFile> getKKSFile(u32_t tm, const string &kks_file_name);

    std::shared_ptr<KKSFile> getCurrentKKSFile();

    void kks2json(ostream &os, time_t tm, KKSFile::KKS_Value *v, bool float_fmt = false, char type = 'A');

    //显示多个kks的最后的值
    void KKSLastValue(ostream &os, const vector<string> tgns);

    /**
     * 通过时间，查找数据；当前数据的时间范围不可以跨天
     * @param os    输出流
     * @param tgn   测点名
     * @param stime 开始时间
     * @param etime 结束时间
     */
    void history(ostream &os, const string &tgn, time_t stime, time_t etime);

    void history(ostream &os, const string &tgn, u32_t kks_id, time_t stime, time_t etime);

    void getKKSHistory(u32_t kid, time_t stime, time_t etime, vector<KKS_Value> &values);

    /**
     * 获取一些点，最后时间的值
     * @param os
     * @param kks
     */
    void getMultiKKSFromCache(ostream &os, const vector<string> &kks);

    void getMultiKKSFromCache(const vector<string> &kks, map<string, KKSManger::KKS_Value> &value);

    void getMultiKKSFromCache(const vector<u32_t> &kids, map<u32_t, KKSManger::KKS_Value> &values);

    /**
     * 获取某个测点，当前m分钟内的数据，注意在超出当天时间范围内的数据不做回溯处理；也就是凌晨时分的数据，可能为空
     * @param kks
     * @param minute
     */
    void getKKSValueIntMinute(ostream &os, const string &kks, int minute);

private:
    std::mutex _mux;
    //std::shard_mutex _cache_write_read_lock;
    TL_ThreadRwLock _cache_write_read_lock;
    KKSIndex _kks_index;
    map<u32_t, std::shared_ptr<KKSFile> > _kks_file; //每天一个文件
    map<time_t, deque<KKS_Value> > _kks_value_cache; //记录最近的几个点,用于高速查询与去重
    string _kfile_path{"/tmp"};
};

#endif /* KKSMANGER_H */

